{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b1872b11",
   "metadata": {},
   "source": [
    "# Memory in Bedrock AgentCore"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "53072ad9",
   "metadata": {},
   "source": [
    "Bedrock AgentCore Memory is a managed AWS service that allows you to create and manage memory resources that store conversation contexts for agents."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0fc53ef",
   "metadata": {},
   "source": [
    "To get started, you will need to install LlamaIndex and the AgentCore Memory integration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "36f4fd2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install llama-index llama-index-memory-bedrock-agentcore llama-index-llms-bedrock-converse"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "130ba50b",
   "metadata": {},
   "source": [
    "### Bedrock AgentCore Setup Pre-Requisites\n",
    "\n",
    "1. AWS account with Bedrock AgentCore access\n",
    "2. Configured AWS credentials (boto3)\n",
    "3. Created memory resource in AWS Bedrock AgentCore\n",
    "4. Required IAM permissions:\n",
    "   1. bedrock-agentcore:CreateEvent\n",
    "   2. bedrock-agentcore:ListEvents\n",
    "   3. bedrock-agentcore:RetrieveMemories"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0df5a87e",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "Create an instance of AgentCoreMemoryContext to setup the memory resources that you will need for building an agent.\n",
    "   1. Actor id → This is a required field and it is the identifier of the actor (could be an agent or the end-user).\n",
    "   2. Memory id → This is a required field and it is the identifier of the memory store.\n",
    "   3. Session id → This is a required field and it is the unique identifier of a particular conversation.\n",
    "   4. Namespace → This is an optional field and it is used to determine how to extract long term memories. By default it will use “/” as the namespace.\n",
    "   5. Memory strategy id → This is an optional field and it is the identifier for a memory strategy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f6fcfcd",
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.memory.bedrock_agentcore import (\n",
    "    AgentCoreMemory,\n",
    "    AgentCoreMemoryContext,\n",
    ")\n",
    "\n",
    "context = AgentCoreMemoryContext(\n",
    "    actor_id=\"<REQUIRED>\",\n",
    "    memory_id=\"<REQUIRED>\",\n",
    "    session_id=\"<REQUIRED>\",\n",
    "    memory_strategy_id=\"<OPTIONAL>\",\n",
    "    namespace=\"<OPTIONAL>\",\n",
    ")\n",
    "agentcore_memory = AgentCoreMemory(context=context)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7366bdc7",
   "metadata": {},
   "source": [
    "## Usage\n",
    "\n",
    "Initialize the FunctionAgent or ReActAgent with any tool and LLM.\n",
    "\n",
    "Below we define some dummy tools to have the agent interact with."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a25d58ac",
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.llms.bedrock_converse import BedrockConverse\n",
    "from llama_index.core.agent.workflow import FunctionAgent\n",
    "from llama_index.core.tools import FunctionTool\n",
    "\n",
    "\n",
    "async def call_fn(name: str, message: str):\n",
    "    \"\"\"Call the provided name.\n",
    "    Args:\n",
    "        name: str (Name of the person, will lookup their phone number)\n",
    "        message: str (Message to send)\n",
    "    \"\"\"\n",
    "    print(f\"Called {name} and left a message.\")\n",
    "\n",
    "\n",
    "async def email_fn(email: str, message: str):\n",
    "    \"\"\"Email the provided name.\n",
    "    Args:\n",
    "        email: str (Email to send to)\n",
    "        message: str (Body of the email)\n",
    "    \"\"\"\n",
    "    print(f\"Emailing {email} with the provided message.\")\n",
    "\n",
    "\n",
    "llm = BedrockConverse(model=\"us.anthropic.claude-sonnet-4-20250514-v1:0\")\n",
    "\n",
    "\n",
    "agent = FunctionAgent(\n",
    "    tools=[email_fn, call_fn],\n",
    "    llm=llm,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "760c9700",
   "metadata": {},
   "source": [
    "Invoke the agent's tool to store this in memory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "10fc5e27-acbe-4c05-98a2-f5d4e0777552",
   "metadata": {},
   "outputs": [],
   "source": [
    "response = await agent.run(\n",
    "    \"Please email johan@coolcompany.com and tell him that his appointement has been moved to 3 PM January 10th, 2025.\",\n",
    "    memory=agentcore_memory,\n",
    ")\n",
    "\n",
    "print(str(response))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8a50746",
   "metadata": {},
   "source": [
    "Query the agent to consult its memory source for the response."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c08b2d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "response = await agent.run(\n",
    "    \"Who have I emailed recently?\", memory=agentcore_memory\n",
    ")\n",
    "\n",
    "print(str(response))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa55ebd9",
   "metadata": {},
   "source": [
    "## References\n",
    "\n",
    "- [Bedrock AgentCore Memory Documentation](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/memory-getting-started.html)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "llama_index",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
